package ru.batrdmi.svnplugin.logic;

import org.jetbrains.annotations.NotNull;
import org.tmatesoft.svn.core.SVNLogEntryPath;

import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import static org.tmatesoft.svn.core.io.SVNRepository.INVALID_REVISION;

public class Revision {
    public static enum LinkType {COPY, MERGE}

    private final long revisionNumber;
    private final String author;
    private final Date date;
    private final String message;
    private final String relPath;
    @NotNull
    private final List<Revision> copiedOrMergedRevisions;
    private final LinkType linkType;
    private final char changeType;

    public Revision(String relPath, long revisionNumber, String author, Date date, String message,
                    @NotNull List<Revision> copiedOrMergedRevisions, LinkType linkType, char changeType) {
        this.author = author;
        this.copiedOrMergedRevisions = copiedOrMergedRevisions;
        this.date = date;
        this.message = message;
        this.relPath = relPath;
        this.revisionNumber = revisionNumber;
        this.linkType = linkType;
        this.changeType = changeType;
    }

    public Revision(String relPath, long revisionNumber) {
        this.relPath = relPath;
        this.revisionNumber = revisionNumber;
        this.changeType = 0;
        this.author = null;
        this.date = null;
        this.message = null;
        this.copiedOrMergedRevisions = Collections.emptyList();
        this.linkType = null;
    }

    public String getAuthor() {
        return author;
    }

    @NotNull
    public List<Revision> getCopiedOrMergedRevisions() {
        return copiedOrMergedRevisions;
    }

    public long getLinkedRevisionNumber() {
        return copiedOrMergedRevisions.isEmpty() ? INVALID_REVISION : copiedOrMergedRevisions.get(0).getRevisionNumber();
    }

    public String getLinkedRelPath() {
        return copiedOrMergedRevisions.isEmpty() ? null : copiedOrMergedRevisions.get(0).getRelPath();
    }

    public LinkType getLinkType() {
        return linkType;
    }

    public Date getDate() {
        return date;
    }

    public String getMessage() {
        return message;
    }

    public String getRelPath() {
        return relPath;
    }

    public long getRevisionNumber() {
        return revisionNumber;
    }

    public char getChangeType() {
        return changeType;
    }

    public boolean isDeleted() {
        return changeType == SVNLogEntryPath.TYPE_DELETED;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Revision revision = (Revision) o;

        if (revisionNumber != revision.revisionNumber) return false;
        if (relPath != null ? !relPath.equals(revision.relPath) : revision.relPath != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = (int) (revisionNumber ^ (revisionNumber >>> 32));
        result = 31 * result + (relPath != null ? relPath.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return relPath + "@" + revisionNumber;
    }

    public static class RevisionNumberComparator implements Comparator<Revision> {
        public int compare(Revision o1,Revision o2)
        {
            long rev1 = o1.getRevisionNumber();
            long rev2 = o2.getRevisionNumber();
            return (rev1 > rev2) ? 1 : ((rev1 < rev2) ? -1 : 0);
        }
    }
}
